/**
 *  
 *  Copyright (c) 2011,
 *  GaoTime
 *  All rights reserved.
 *   
 *  @file       Tools.h
 *  @brief      基础定义声明
 *   
 *  该文件为重要库文件，请不要修改该文件，如需修改，请通知管理人员，由相关人员进行修改后重新发布库文件
 *   
 *  @version    1.1
 *  @author     imuse
 *  @date       2011-06-16
 *   
 *   
 *  修订说明：最初版本  
 */
#ifndef TOOLS_H
#define TOOLS_H

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <unistd.h>

#include <math.h>

///最大路径长度
#define MAX_PATH 512

#define MAX_LENG_PATH 1024


/*基础类型定义*/
#ifndef TBOOL
///bool类型定义
typedef unsigned char   TBOOL;
///真
#define TRUE		1
///假
#define FALSE		0
#endif

///64位长整型
typedef long long long64;
///无符号短整型 
typedef unsigned short	u_short;
///无符号字节
typedef unsigned char	u_byte;
///无符号整型
typedef unsigned int	u_int;
///有符号字节
typedef char byte;

/*内存管理相关*/
///申请一个新的内存空间
#define Tools_Malloc(nSize) memset(malloc(nSize), 0, nSize)
///释放一个内存空间
#define Tools_Free(aPtr) free(*aPtr),*aPtr = NULL

/*数据类型转找相关*/
///字符串转int
#define _a2i(a) atoi(a)
///字符串转float
#define _a2f(a) atof(a)
///字符串转64位长整型
#define _a2ll(a) atoll(a)
///字符转short
#define _a2s(a) (short)_a2i(a)
///int转字符串
#define _i2a(i, a) sprintf(a, "%d", i)
///字节转整型，指定字节偏移位置
#define _b2i(a,i) ((a[i]&0xFF)<<24)+((a[i+1]&0xFF)<<16)+((a[i+2]&0xFF)<<8)+(a[i+3]&0xFF)
///整型转字节
#define _i2b(i,a) a[0]=((i>>24)&0xFF);a[1]=((i>>16)&0xFF);a[2]=((i>>8)&0xFF);a[3]=(i&0xFF)
///字节转整型
#define _b2i0(a) _b2i(a,0)
///字节转短整型，指定字节偏移位置
#define _b2s(a,i) ((a[i+0]&0xFF)<<8)+(a[i+1]&0xFF)
///短整型转字节
#define _s2b(i,a) a[0]=((i>>8)&0xFF);a[1]=(i&0xFF)
///字节转短整型
#define _b2s0(a) _b2s(a,0)

//#define _mov(a,i) (a&0xFF)<<i
//#define BytesToLong64(a,i) _mov(a[i],56)+_mov(a[i+1],48)+_mov(a[i+2],40)+_mov(a[i+3],32)+_mov(a[i+4],24)+_mov(a[i+5],16)+_mov(a[i+6],8)+_mov(a[i+7],0)
//#define Long64ToBytes(i,a) a[0]=((i>>56)&0xFF);a[1]=((i>>48)&0xFF);a[2]=((i>>40)&0xFF);a[3]=((i>>32)&0xFF);a[4]=((i>>24)&0xFF);a[5]=((i>>16)&0xFF);a[6]=((i>>8)&0xFF);a[7]=(i&0xFF)

///短整型转字节
#define ShortToBytes(i,a) _s2b(i,(a))
///字节转整型
#define BytesToInt(a,i) (_b2i((a),i))
///字节转短整型
#define BytesToShort(a,i) _b2s((a),i)
///整型转字节
#define IntToBytes(i,a) _i2b(i,(a));

///字节转float,该方法与业务相关，
#define BytesToFloat(a,i) ((BytesToInt(a,i))/10000.0)

///16进制字符串转整型
#define ColorTools_HexToColor(a) HexToColor(a)

///计算两个时间分钟差，入参为小时分钟结构
#define CalcTimeDiffer(s, e) (((e/100)-(s/100))*60+((e%100)-(s%100)))
///格式化日期到字符串
#define FormatHoursMinute(s,hhmm) sprintf(s,"%02d:%02d",hhmm/100,hhmm%100) 

/*数学计算相关*/
#ifndef max
///取最大值
#define max(a,b)            (((a) > (b)) ? (a) : (b))
#endif


#ifndef minz
///取a和b中的最小值，如果b小于0，取a的值为最大值
#define minz(a,b)           (b<=0)?(a): (((a) < (b)) ? (a) : (b))
#endif


#ifndef min
///取最小值
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#endif

#ifndef absf
///取浮点数的绝对值
#define absf(f) fabs(f)
#endif

#ifndef absl
#define absl(l) l>=0?l:(-l)
#endif

/*系统等待相关*/
#ifndef SLEEP
//linux 下 usleep是等待毫秒，sleep是等待秒
///让当前线程暂停n毫秒
#define SLEEP(a)			usleep(a*1000)
#endif

///计算求模
#define _mod(a,b)     (((a % b) > 0) ? ((a % b) == 0) ? (a / b) : ((a / b) + 1) : (a / b))

/*字符串相关*/
///判断字符串a是否等于b
#define strestr(a,b)		(strcmp(a,b)==0)

/*utf-8转码相关*/
///utf-8转码相关
#define MASKBITS	0x3F
///utf-8转码相关
#define MASKBYTE	0x80
///utf-8转码相关
#define MASK2BYTES	0xC0
///utf-8转码相关
#define MASK3BYTES	0xE0
///utf-8转码相关
#define MASK4BYTES	0xF0
///utf-8转码相关
#define MASK5BYTES	0xF8
///utf-8转码相关
#define MASK6BYTES	0xFC

/*socket相关*/
///socket错误代码
#define SOCKET_ERROR -1
///socket错误代码
#define WSAECONNRESET 10054L
///socket错误代码
#define WSAENOBUFS    10055L

/*晃动检测相关*/
///晃动检测相关
#define kAccelerometerFrequency			25 //Hz
///晃动检测相关
#define kFilteringFactor				0.1
///晃动检测相关
#define kMinEraseInterval				0.5
///晃动检测相关
#define kEraseAccelerationThreshold		2.0

//void* MMalloc(int nSize);
//void FFree(void **aPtr);



///列数据链表
typedef struct COL_NODE_tag {
    
	char *text;                 /**<内容*/
	struct COL_NODE_tag *next;  /**<下一个列节点指针*/
} COL_NODE;

///行数据链表
typedef struct ROW_NODE_tag {
	char *buf;                  /**<数据缓存，只有头节点存在。请不要对它进行任何修改*/
	COL_NODE *node;             /**<列链表头节点*/
	struct ROW_NODE_tag *next;  /**<下一个行节点指*/
} ROW_NODE;

/**把一个字符串按指定分隔符拆分成一维单向链表,请不要在使用COL_NODE周期内释放pSrc
 *
 *  @param char		*pSrc		源字符串
 *  @param char		c			分隔符
 *
 *	@return COL_NODE*	拆分后的链表头结点
 *  @note
 */
COL_NODE* StringSplit(char *pSrc, char c);

/**把一个字符串按指定分隔符拆分成一维单向链表,请不要在使用COL_NODE周期内释放pSrc
 *
 *  @param char		*pSrc		源字符串
 *  @param char		*pStr		分隔字符
 *
 *  @return COL_NODE*	拆分后的链表头结点
 *  @note
 */
COL_NODE* StringSplitStr(char *pSrc, char *pStr);

/**把一个字符串按指定分隔符拆分成二维单向链表,请不要在使用ROW_NODE周期内释放pSrc
 *
 *  @param char		*pSrc		源字符串
 *  @param char		r			行分隔符
 *  @param char		c			列分隔符
 *
 *  @return ROW_NODE*	拆分后的链表行头结点
 *  @see    StringSplit
 *  @note
 */
ROW_NODE* StringSplitRowCol(char *pSrc, char r, char c);

/**把一个字符串按指定分隔符拆分成二维单向链表,请不要在使用ROW_NODE周期内释放pSrc
 *
 *  @param char		*pSrc		源字符串
 *  @param char		*pRStr		行分隔字符串
 *  @param char		*pCStr		列分隔字符串
 *
 *  @return ROW_NODE*	拆分后的链表行头结点
 *  @see    StringSplitStr
 *  @note
 */
ROW_NODE* StringSplitRowColStr(char *pSrc, char *pRStr, char *pCStr);

/**释放一个一维单向链表
 *
 *  @param COL_NODE **pNode	单向链表头结点指针的指针
 *  @return -
 *  @note
 */
void FreeColNode(COL_NODE **pNode);

/**释放一个二维单向链表
 *
 *  @param ROW_NODE **pNode	单向链表行头结点指针的指针
 *
 *  @return -
 *  @note
 */
void FreeRowNode(ROW_NODE **pNode);

/**获取一维链表的结点个数
 *
 *  @param COL_NODE *pNode	二维链表行头结点指针
 *
 *  @return int				总列数
 *  @note
 */
int GetColCount(COL_NODE *pNode);

/**获取二维链表的行数
 *
 *  @param ROW_NODE *pNode	二维链表行头结点指针
 *
 *  @return int				总行数
 *  @note
 */
int GetRowCount(ROW_NODE *pNode);

/**获取UTF-8编码转成UNICODE（UTF-16LE）编码后所需要的字节大小
 *
 *  @param char		*pSrc		源BUF指针
 *  @param int			nLen		源BUF大小
 *
 *  @return int 转换后的字节大小
 *  @note
 */
int Utf8ToUnicodeLength(char *pSrc, int nLen);

/**将UTF-8编码转成UNICODE（UTF-16LE）编码
 *
 *  @param char		*pSrc		源BUF指针
 *  @param int			nLen		源BUF大小
 *  @param char		*pDes		转换后的BUF指针
 *
 *  @return -
 *  @note
 */
void Utf8ToUnicode(char *pSrc, int nLen, char *pDes);

/**将UTF-8编码转成UNICODE（UTF-16LE）编码
 *
 *  @param char		*pSrc		源BUF指针
 *
 *  @return char*   转换后的buf指针
 *  @note   调用后需要主动释放返回指针
 */
char* Utf8ToUnicodeEx(char *pSrc);

/**获取UNICODE（UTF-16LE）编码转成UTF-8编码后所需要的字节大小
 *
 *  @param char		*pSrc		源BUF指针
 *  @param int			nLen		源BUF大小
 *
 *  @return int 转换后的字节大小
 *  @note
 */
int UnicodeToUtf8Length(char *pSrc, int nLen);

/**将UNICODE（UTF-16LE）编码转成UTF-8编码
 *
 *  @param char		*pSrc		源BUF指针
 *  @param int			nLen		源BUF大小
 *  @param char		*pDes		转换后的BUF指针
 *  @return -
 *  @note
 */
void UnicodeToUtf8(char *pSrc, int nLen, char *pDes);

/**将UNICODE（UTF-16LE）编码转成UTF-8编码
 *
 *  @param char		*pSrc		源BUF指针
 *
 *  @return char*   转换后的buf指针
 *  @note   调用后需要主动释放返回指针
 */
char* UnicodeToUtf8Ex(char *pSrc);

/**获取UNICODE（UTF-16LE）字符串的字符个数
 *
 *  @param char		*pSrc		源BUF指针
 *
 *  @return int
 *  @note
 */
int GetUnicodeStringLength(char *pSrc);

/**字节转64位长整型
 *
 *  @param char		*pSrc		源BUF指针
 *  @param int		nPos		偏移位置
 *
 *  @return long64
 *  @note
 */
long64 BytesToLong64(char *pSrc, int nPos);

/**64位长整型转字节
 *
 *  @param long64	n           要转的64位长整型
 *  @param char     *pDst		目标缓存
 *
 *  @return -
 *  @note
 */
void Long64ToBytes(long64 n, char *pDst);



/**计算一个字符串的hash值
 *
 *  @param char* str            要计算的字符地址
 *
 *  @return u_int   计算后的hash值
 *  @note
 */
u_int ELFHash(char* str);

void CharToHex(char *pSrc, int nLen, char *pDes);

/**16进制字符串转整型24位颜色RGB(8,8,8)
 *
 *  @param char* pSrc            源字符
 *
 *  @return int   转换后的24位色
 *  @note
 */
int HexToColor(char *pSrc);

/**内存从前向后移动
 *
 *  @param char*    pSrc            源地址
 *  @param char*    pDsc            目标地址
 *  @param int      nLen            移动大小
 *
 *  @return －
 *  @note
 */
void MOVEMEM(char *pSrc, char *pDsc, int nLen);

/**int型时期转成long64日期
 *
 *  @param int      intDateTime      源int型日期
 *
 *  @return long64  64位长整型
 *  @note
 */
long64 DateTimeInt2Long(int intDateTime);

/**16进制字符串转内存值
 *
 *  @param char*    pSrc            源字符
 *  @param int      nLen            源字符长度
 *  @param char*    pSrc            目标地址
 *
 *  @return －
 *  @note
 */
void HexToChar(char *pSrc, int nLen, char *pDes);


/*
 新行情协议中所使用可变数据
 */
//读取int大小数值（32位）
void readInt(void *p, int *n, int *nc);
//读取long64大小数据(64位)
void readLong(void *p, long long *n, int *nc);
//读取一个近似压缩算法的数值
void readRLong(void *p, long long *l);

long64 StringToLong(char *pSrc, int nLen);
#endif
